package com.example.venue_reservation_service.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.venue_reservation_service.domain.Information;
import com.example.venue_reservation_service.domain.InformationTime;
import com.example.venue_reservation_service.dto.PageDTO;
import com.example.venue_reservation_service.exception.MinioRemoveException;
import com.example.venue_reservation_service.mapper.InformationMapper;
import com.example.venue_reservation_service.mapper.TypeMapper;
import com.example.venue_reservation_service.domain.Type;
import com.example.venue_reservation_service.service.TypeService;
import com.example.venue_reservation_service.utils.MinioUtil;
import com.example.venue_reservation_service.vo.QueryVO;
import com.example.venue_reservation_service.vo.Result;
import com.example.venue_reservation_service.vo.TypeVO;
import jakarta.annotation.Resource;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Base64;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@Service
public class TypeServiceImpl extends ServiceImpl<TypeMapper, Type>
    implements TypeService{

    @Resource
    private MinioUtil minioUtil;

    @Resource
    private InformationMapper informationMapper;

    @Value("${access.url}")
    private String imgPrefix;

    @Override
    public Result queryTypes(PageDTO dto) {
        Page<Type> page = new Page<>(dto.getCurrent(), dto.getSize());
        page = page(page, null);
        List<Type> records = page.getRecords();
        records.forEach(item -> {
            if(StringUtils.isNotBlank(item.getImgUrl())){
                item.setImgUrl(imgPrefix + item.getImgUrl());
            }
        });
        QueryVO<Type> vo = new QueryVO<>();
        vo.setList(records);
        vo.setTotal(page.getTotal());
        return Result.ok(vo).message("场馆信息获取成功");
    }

    private boolean isSame(Type type){
        Type one = getOne(Wrappers.<Type>lambdaQuery()
                .eq(Type::getVname, type.getVname())
                .eq(Type::getLocation, type.getLocation()));
        return Optional.ofNullable(one).isPresent();
    }

    @Override
    public Result addType(Type type) {
        if (isSame(type)) {
            return Result.fail().message("该场馆已经存在");
        }
        save(type);
        return Result.ok().message("场馆信息保存成功");
    }

    @Override
    public String loadImg(Integer tid) {
        String imgUrl = getById(tid).getImgUrl();
        try {

            // 创建URL对象
            URL url = new URL(imgUrl);
            // 打开连接并获取输入流
            try (InputStream in = url.openStream()) {
                // 使用ByteArrayOutputStream收集字节
                ByteArrayOutputStream out = new ByteArrayOutputStream();

                // 缓冲区
                byte[] buffer = new byte[1024];
                int bytesRead;

                // 读取并写入输出流
                while ((bytesRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                }

                // 获取字节数组
                byte[] imageBytes = out.toByteArray();

                // 将字节数组编码为Base64字符串
                return Base64.getEncoder().encodeToString(imageBytes);
            }
        }catch (Exception e){
            e.printStackTrace();
            return "null";
        }
    }

    @Override
    public Result upload(Integer id, MultipartFile file) {
        Type type = getById(id);
        if (Optional.ofNullable(type).isEmpty()) {
            return Result.fail().message("场馆信息不存在");
        }
        if(StringUtils.isNotBlank(type.getImgUrl())){
            try{
                minioUtil.removeFile(type.getImgUrl());
            }catch (Exception e){
                throw new MinioRemoveException("场馆图片异常，请稍后重试");
            }
        }
        // 对照片重新命名
        String extension = FilenameUtils.getExtension( file.getOriginalFilename());

        try {
            // 重新生成文件名称
            String filename = UUID.randomUUID() + "-" + id + "." + extension;
            // 调用minio接口上传照片
            minioUtil.uploadFile(file, filename, file.getContentType());
            type.setImgUrl(filename);
            updateById(type);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail().message("图片上传失败");
        }

        return Result.ok().message("图片上传成功");
    }

    @Override
    public Result updateType(Type type) {
        // 获取初始场馆数据
        Type original = getById(type.getId());
        // 判断是否修改了场馆的名字
        String originalName = original.getVname();
        if (!originalName.equals(type.getVname())) {
            // 修改，判断是否存在其他同名场馆
            if (Optional.ofNullable(getOne(Wrappers.<Type>lambdaQuery().eq(Type::getVname, type.getVname()))).isPresent()) {
                return Result.fail().message("存在同名场馆");
            }
        }
        updateById(type);
        return Result.ok().message("场地信息修改成功");
    }

    @Override
    public Result delType(Integer id) {
        Type type = getById(id);
        if (Optional.ofNullable(type).isEmpty()) {
            return Result.fail().message("场馆信息不存在");
        }
        // 判断当前场馆是否存在场地信息
        List<Information> list = informationMapper.selectList(Wrappers
                .<Information>lambdaQuery()
                .eq(Information::getTypeId, id));
        if (list.size()> 0) {
            return Result.fail().message("请先移除场地信息");
        }

        // 移除场地照片
        String imgUrl = type.getImgUrl();
        if (StringUtils.isNotBlank(imgUrl)){
            minioUtil.removeFile(imgUrl);
        }
        removeById(id);
        return Result.ok().message("场馆信息移除成功");
    }

    @Override
    public Result getNames() {
        List<TypeVO> vos = list().stream().map(obj -> BeanUtil.copyProperties(obj, TypeVO.class)).toList();
        return Result.ok(vos).message("场馆列表获取成功");
    }


}




